﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//2.链表的节点数据结构；
struct LinkNodePointer
{
	struct LinkNodePointer* next;
};
//3.链表的结构体；
struct LListPointer
{
	//4.头节点；
	struct LinkNodePointer header;
	int size;
};
typedef void* LinkListPointer;

struct PersonNode
{
	struct LinkNodePointer node;
	char name[64];
	int age;
};

//5.初始化链表；
LinkListPointer Init_LListPointer()
{
	struct LListPointer* list = malloc(sizeof(struct LListPointer));
	if (NULL == list)
	{
		return NULL;
	}
	list->header.next = NULL;
	list->size = 0;

	return list;
}

void Insert_LListPointer(LinkListPointer list, int position, void* data)
{
	if (NULL == list)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	struct LListPointer* myList = (struct LListPointer*)list;
	struct LinkNodePointer* myNode = (struct LinkNodePointer*)data;
	if (position<0 || position>myList->size)
	{
		position = myList->size;
	}

	//6.找位置，即position位置的前一个位置pCurrent；pCurrent为position位置的前一个节点地址；
	struct LinkNodePointer* pCurrent = &(myList->header);
	for (int i = 0; i < position; ++i)
	{
		pCurrent = pCurrent->next;
	}

	//7.数据插入链表；
	myNode->next = pCurrent->next;
	pCurrent->next = myNode;

	myList->size++;
}

void Foreach_LListPointer(LinkListPointer list, void(*myForeach)(void*))
{
	if (NULL == list)
	{
		return;
	}
	if (NULL == myForeach)
	{
		return;
	}

	struct LListPointer* myList = (struct LListPointer*)list;
	struct LinkNodePointer* pCurrent = myList->header.next;
	while (pCurrent != NULL)
	{
		struct LinkNodePointer* pNext = pCurrent->next;
		myForeach(pCurrent);
		pCurrent = pNext;
	}
}
void myPrintPointer(void* data)
{
	struct PersonNode* person = (struct PersonNode*)data;
	printf("12.输出链表节点person的数据Name：%s  Age：%d\n", person->name, person->age);
}

//13.删除节点元素；
void RemoveByPos_LListPointer(LinkListPointer list, int position)
{
	if (NULL == list)
	{
		return;
	}
	struct LListPointer* myList = (struct LListPointer*)list;
	if (position<0 || position>myList->size - 1)
	{
		return;
	}

	//14.辅助指针；
	struct LinkNodePointer* pCurrent = &(myList->header);
	for (int i = 0; i < position; ++i)
	{
		pCurrent = pCurrent->next;
	}
	//15.缓存一下待删除的节点；
	struct LinkNodePointer* pDel = pCurrent->next;

	//16.重新建立待删除节点的前驱和后继节点关系；header头结点没有实际意义，只是为了表示链表的起始；
	pCurrent->next = pDel->next;
	myList->size--;
}

//17.销毁链表；
void Destroy_LListPointer(LinkListPointer list)
{
	if (NULL == list)
	{
		return;
	}
	free(list);
	list = NULL;
}

void testOneWayLinkListPointer()
{
	//8.初始化链表；
	LinkListPointer list = Init_LListPointer();

	//9.创建数据；
	struct PersonNode p1 = { NULL,"aaa",10 };
	struct PersonNode p2 = { NULL,"bbb",20 };
	struct PersonNode p3 = { NULL,"ccc",30 };
	struct PersonNode p4 = { NULL,"ddd",40 };
	struct PersonNode p5 = { NULL,"eee",50 };

	//10.插入数据；
	Insert_LListPointer(list, 0, &p1);
	Insert_LListPointer(list, 0, &p2);
	Insert_LListPointer(list, 0, &p3);
	Insert_LListPointer(list, 0, &p4);
	Insert_LListPointer(list, 0, &p5);

	//11.遍历链表；
	Foreach_LListPointer(list, myPrintPointer);//50,40,30,20,10

	//18.删除索引为3的元素节点20；
	RemoveByPos_LListPointer(list, 3);
	printf("----------------19.输出删除20的链表元素数据：--------------------\n");
	//11.遍历链表；
	Foreach_LListPointer(list, myPrintPointer);//50,40,30,10

	//20.销毁链表；
	Destroy_LListPointer(list);

#if 0
	struct LinkNodePointer* pp1 = (struct LinkNodePointer*)&p1;
	struct LinkNodePointer* pp2 = (struct LinkNodePointer*)&p2;
	struct LinkNodePointer* pp3 = (struct LinkNodePointer*)&p3;
	struct LinkNodePointer* pp4 = (struct LinkNodePointer*)&p4;
	struct LinkNodePointer* pp5 = (struct LinkNodePointer*)&p5;

	pp1->next = pp2;
	pp2->next = pp3;
	pp3->next = pp4;
	pp4->next = pp5;
	pp5->next = NULL;

	struct LinkNodePointer* pCurrent = pp1;
	while (pCurrent != NULL)
	{
		struct PersonNode* person = (struct PersonNode*)pCurrent;
		printf("1.输出单向链表元素节点person的Name：%s  Age：%d\n", person->name, person->age);//10,20,30,40,50
		pCurrent = pCurrent->next;
	}
#endif

}

//main223：单向链表指针初始化插入遍历删除销毁
int main223()
{
	testOneWayLinkListPointer();

	system("pause");
	return EXIT_SUCCESS;
}